package com.javaee.wordtree.controller;

import com.javaee.wordtree.common.Result;
import com.javaee.wordtree.entity.Message;
import com.javaee.wordtree.entity.MessageWithRagInfo;
import com.javaee.wordtree.service.MessageRagService;
import com.javaee.wordtree.mapper.MessageMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.List;

/**
 * 示例：带RAG信息的消息控制器
 */
@RestController
@RequestMapping("/api/messages")
@RequiredArgsConstructor
@Slf4j
public class MessageRagController {

    private final MessageRagService messageRagService;
    private final MessageMapper messageMapper;

    /**
     * 创建带RAG信息的消息（模拟您提供的JSON格式）
     * 
     * @param request 消息请求
     * @return 统一响应格式
     */
    @SuppressWarnings("unchecked")
    @PostMapping("/with-rag")
    public Result<MessageWithRagInfo> createMessageWithRag(@RequestBody CreateMessageWithRagRequest request) {
        try {
            // 创建RAG结果列表
            List<MessageWithRagInfo.RagResultSummary> ragResults = new ArrayList<>();
            for (int i = 0; i < 5; i++) {
                MessageWithRagInfo.RagResultSummary summary = new MessageWithRagInfo.RagResultSummary();
                summary.setSimilarity(0.14285714285714285);
                summary.setQuestionSummary("When should I use \"shall\" versus \"will\"?\nWhich is ...");
                summary.setAnswerSummary(
                        "Here is a good description of when to use shall:\n\n\n  ...shall is used for the future tense\n  with th...");
                ragResults.add(summary);
            }

            // 创建RAG增强信息
            MessageWithRagInfo.RagEnhancementInfo ragInfo = new MessageWithRagInfo.RagEnhancementInfo();
            ragInfo.setBasedOnRag(true);
            ragInfo.setRagCount(5);
            ragInfo.setValidRagCount(5);
            ragInfo.setAverageSimilarity(0.14285714285714285);
            ragInfo.setMaxSimilarity(0.14285714285714285);
            ragInfo.setMinSimilarity(0.14285714285714285);
            ragInfo.setSimilarityThreshold(0.1);
            ragInfo.setRagResults(ragResults);

            // 创建消息
            MessageWithRagInfo messageWithRagInfo = messageRagService.createMessageWithRagInfo(
                    request.getChatId(),
                    request.getText(),
                    false, // AI回复，非用户消息
                    ragInfo);

            // 转换为Message实体并保存到数据库
            Message message = messageRagService.convertToMessage(messageWithRagInfo);
            messageMapper.insert(message);

            // 设置返回的messageId
            messageWithRagInfo.setMessageId(message.getMessageId());

            return Result.success(messageWithRagInfo);
        } catch (Exception e) {
            log.error("创建RAG消息时发生错误", e);
            Result<MessageWithRagInfo> errorResult = Result.error("500", "创建消息失败");
            return errorResult;
        }
    }

    /**
     * 根据聊天ID获取所有消息（包含RAG信息）
     * 
     * @param chatId 聊天ID
     * @return 消息列表
     */
    @SuppressWarnings("unchecked")
    @GetMapping("/chat/{chatId}")
    public Result<List<MessageWithRagInfo>> getMessagesByChatId(@PathVariable Integer chatId) {
        try {
            List<Message> messages = messageMapper.findMessagesByChatId(chatId);
            List<MessageWithRagInfo> messagesWithRagInfo = messageRagService.convertToMessageWithRagInfoList(messages);
            return Result.success(messagesWithRagInfo);
        } catch (Exception e) {
            log.error("获取聊天消息时发生错误", e);
            Result<List<MessageWithRagInfo>> errorResult = Result.error("500", "获取消息失败");
            return errorResult;
        }
    }

    /**
     * 创建消息请求DTO
     */
    public static class CreateMessageWithRagRequest {
        private Integer chatId;
        private String text;

        // Getters and Setters
        public Integer getChatId() {
            return chatId;
        }

        public void setChatId(Integer chatId) {
            this.chatId = chatId;
        }

        public String getText() {
            return text;
        }

        public void setText(String text) {
            this.text = text;
        }
    }
}
